﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Data;
using ProgNetComponentsDx.Browsers;
using ProgNetComponentsDx.Options;
using System.IO;
using ProgNetComponents.Classes;
using ProgNetComponents.Data.SqlCe;
using System.Text.RegularExpressions;
using BuildHelper.Scheduler;
using System.Threading.Tasks;

namespace BuildHelper.Work.GUI
{
    public static class BudowanieGuiTools
    {
        public static void ReadBranch(string brancz, GUI.GuiDataSet guiDataSet1, out string sVs, out string sKonfig)
        {
            BuildHelper.Setup.Brancze.BranczeDataSet branczeDataSet1 = new Setup.Brancze.BranczeDataSet();
                branczeDataSet1.STP_BRANCZE.Clear();
            branczeDataSet1.STP_BRANCZE_APPS.Clear();
            guiDataSet1.Clear();
            NamedObject o = new NamedObject("@BRANCZ", brancz);
            SqlCeDataManager sqlCeDataManager1 = new SqlCeDataManager();
            sqlCeDataManager1.AutoLogExceptions = true;
            sqlCeDataManager1.AddTableDef(branczeDataSet1.STP_BRANCZE, "SELECT * FROM STP_BRANCZE WHERE STP_BR_NAZWA = @BRANCZ");
            sqlCeDataManager1.AddTableDef(branczeDataSet1.STP_BRANCZE_APPS, "SELECT A.* FROM STP_BRANCZE_APPS A, STP_APPS B WHERE  A.STP_BR_APP_APP = B.STP_APP_KOD and B.STP_APP_IS_GUI = 1 AND STP_BR_APP_BRANCZ = @BRANCZ ORDER BY STP_BR_APP_POZYCJA ASC");
                
            sqlCeDataManager1.FillTable(branczeDataSet1.STP_BRANCZE, o);
            sqlCeDataManager1.FillTable(branczeDataSet1.STP_BRANCZE_APPS, o);
            sVs = "";
            sKonfig = "";
            if (branczeDataSet1.STP_BRANCZE.Rows.Count == 1)
            {
                sVs = branczeDataSet1.STP_BRANCZE[0]["STP_BR_VS"].AsString();
                sKonfig = branczeDataSet1.STP_BRANCZE[0]["STP_BR_CONFIG"].AsString();

                string katalog = branczeDataSet1.STP_BRANCZE[0].STP_BR_KATALOG;
                DataRow[] rows = branczeDataSet1.STP_BRANCZE_APPS.Select("", "STP_BR_APP_POZYCJA ASC");
                foreach (DataRow stmRow in rows)
                {

                    string SLN = GlobalTools.GetFullPath(stmRow["STP_BR_APP_SLN"].AsString(), katalog);
                    string DIST = GlobalTools.GetFullPath(stmRow["STP_BR_APP_DIST"].AsString(), katalog);
                    string EXE = GlobalTools.GetFullPath(stmRow["STP_BR_APP_EXE"].AsString(), katalog);

                    BuildHelper.Work.GUI.GuiDataSet.APPSRow row = guiDataSet1.APPS.AddAPPSRow(stmRow["STP_BR_APP_APP"].AsString(), true, DIST, EXE, SLN);
                    string slnText = SLN.ReadFile();
                    if (slnText.IsNotNull())
                    {
                        MatchCollection matches = slnText.XMatches("Project\\(\"\\{([^}]*)?\\}\"\\) = \"([^\"]*)?\", \"([^\"]*)?\", \"\\{([^}]*)?}\"");
                        Dictionary<string, string> csprojs = new Dictionary<string, string>();
                        FileInfo fi = new FileInfo(SLN);
                        DirectoryInfo di = fi.Directory;
                        foreach (Match m in matches)
                        {
                            string name = m.Value.XReplace("Project\\(\"\\{([^}]*)?\\}\"\\) = \"", "").XReplace("\", \"([^\"]*)?\", \"\\{([^}]*)?}\"", "");
                            string code = m.Value.XReplace("Project\\(\"\\{([^}]*)?\\}\"\\) = \"([^\"]*)?\", \"([^\"]*)?\", \"", "").XReplace("\"", "");
                            bool build = slnText.XMatch(code.XEscape() + "\\.Debug\\|(.*)?\\.Build\\.0 = Debug\\|(.*)?");
                            string proj = m.Groups[3].Value;
                            if (proj.XMatch("\\.csproj"))
                            {
                                di = fi.Directory;
                                string dir = fi.DirectoryName;
                                while (proj.StartsWith("..") && di !=null)
                                {
                                    di = di.Parent;
                                    proj = proj.XReplace("..\\".XEscape(), "");
                                }

                                proj = di.FullName + "\\" + proj;
                                guiDataSet1.PROJEKTY.AddPROJEKTYRow(row, name, proj, build, code);
                            }
                        }
                    }
                }
            }
            sqlCeDataManager1.Dispose();
        }
        public static void ApplyTemplate(GuiDataSet guiDataSet1, DataSet TemplateDataSet)
        {
            DataRow t;
            foreach (DataRow r in guiDataSet1.APPS.Rows)
            {
                t = TemplateDataSet.Tables["APPS"].SelectFirstRow("STM = " + r["STM"].AsString().EscapeSql());
                if (t != null)
                    r["BUDUJ"] = t["BUDUJ"];
                else
                    r["BUDUJ"] = false;
            }
            foreach (DataRow r in guiDataSet1.PROJEKTY.Rows)
            {
                t = TemplateDataSet.Tables["PROJEKTY"].SelectFirstRow("STM = " + r["STM"].AsString().EscapeSql() + " AND NAZWA = " + r["NAZWA"].AsString().EscapeSql());
                if (t != null)
                    r["BUDUJ"] = t["BUDUJ"];
                else
                    r["BUDUJ"] = false;
            }
        }
        
        public const string INFO_KONIEC_BUDOWANIA = "Koniec budowania";
        public const string INFO_POCZATEK_BUDOWANIA = "Poczatek budowania";
        public const string INFO_URUCHOM = "---URUCHAMIANIE---";
        public static bool ReadTemplate(GuiDataSet ds, string template)
        {
            bool result = false;
             SqlCeDataManager m =null;
             try
             {
                 m = new SqlCeDataManager();
                 m.AutoLogExceptions = true;
                 string nazwa = template;
                 NamedObject parameter = new NamedObject();
                 parameter.Name = "@NAZWA";
                 parameter.Value = nazwa;
                 byte[] bytes = m.ExecuteScalar("SELECT STP_TMP_XML FROM STP_TEMPLATES WHERE STP_TMP_GRUPA =\'GUI\' AND STP_TMP_NAZWA = @NAZWA", parameter) as byte[];
                 string xml = bytes.ByteArrayToString();
                 ds.ReadXmlString(xml);
                 result = true;
             }
             catch (Exception ex)
             {
                 ex.Log();
             }
             finally
             {
                 if (m != null)
                     m.Dispose();
             }
            return result;
        }

        public static BuildStm[] Buduj(GuiDataSet ds, string visualStudio, Process pBuild, bool runAfretBuild, bool Clean, string config, string env, int? server)
        {
            List<BuildStm> list = new List<BuildStm>();

            pBuild.EchoOff();
            DataRow r = BrowserCache.GetRowForValue(Init.InitFormBrowserNames.Setup.VisualStudio, visualStudio);

            string tools = "";
            bool express = false;
            if (r != null)
            {
                tools = r["STP_VS_SCRIPT"].AsString();
                express = r["STP_VS_EXPRESS"].AsBool();
            }
            
            if (tools.IsNotNull())
                pBuild.Execute("call \"%" + tools + "%vsvars32.bat\"");
            DataRow[] rows = ds.APPS.Select("BUDUJ = 1");

            foreach (DataRow r2 in rows)
            {
                list.Add(new BuildStm(r2["STM"].AsString(), BuildProj(ds, r2["STM"].AsString(), runAfretBuild, Clean, pBuild, config, env, server, express)));
            }
            pBuild.Execute("echo " + INFO_KONIEC_BUDOWANIA);
            return list.ToArray();
        }

        public static BuildStm BudujProjekt(GuiDataSet MainDataSet, string visualStudio, string stm, bool run, bool clean, Process pBuild, string config, string env, int? server)
        {
            pBuild.EchoOff();
            DataRow r = BrowserCache.GetRowForValue(Init.InitFormBrowserNames.Setup.VisualStudio, visualStudio);

            string tools = "";
            if (r != null)
            {
                tools = r["STP_VS_SCRIPT"].AsString();

                if (tools.IsNotNull())
                    pBuild.Execute("call \"%" + tools + "%vsvars32.bat\"");
                int i = BuildProj(MainDataSet, stm, run, clean, pBuild, config, env, server, r["STP_VS_EXPRESS"].AsBool());
                pBuild.Execute("echo " + INFO_KONIEC_BUDOWANIA + " " + stm + " " + DateTime.Now.ToString("G"));
                return new BuildStm(stm, i);
            }
            return new BuildStm(stm, 0);
        }
        /*
        public static void BudujOther(string stm, Process pBuild)
        {
            pBuild.EchoOff();
            string tols = GetVsComnTools();
            if (tols.IsNotEmpty())
                pBuild.Execute("call \"%" + tols + "%vsvars32.bat\"");
            pBuild.CdDir(Tools.BranchTools.GetActiveBranchDir());
            pBuild.Execute("cd nd_src\\gene");
            pBuild.Execute("call apps\\" + stm + "\\src\\buildClient.bat");
            pBuild.Execute("echo " + INFO_KONIEC_BUDOWANIA);
        }
        */
        private static int BuildProj(GuiDataSet ds, string stm, bool run, bool clean, Process pBuild, string config, string env, int? server, bool express)
        {
           int i = SetSln(stm, ds);
            DataRow slnRow = ds.APPS.SelectFirstRow("STM = "+stm.EscapeSql());
            if (slnRow != null)
            {
                string sln = slnRow["SLN"].AsString();
                string tmpSlnFile = sln.XReplace("\\.sln", "_BH_TMP.sln");
                pBuild.Execute("echo " + INFO_POCZATEK_BUDOWANIA + " " + stm );

                if (clean)
                {
                    if(express)
                        pBuild.Execute("msbuild " + tmpSlnFile.AddDoubleQuotes() + " /t:Clean");
                    else
                        pBuild.Execute("devenv " + tmpSlnFile.AddDoubleQuotes() + " /Clean");
                }
                if (express)
                    pBuild.Execute("msbuild " + tmpSlnFile.AddDoubleQuotes() + " /t:Build /v:d /p:Configuration=" + config + (config.XMatch("debug")? " /p:DebugSymbols=true" : "") );
                else
                    pBuild.Execute("devenv " + tmpSlnFile.AddDoubleQuotes() + " /Deploy " + config);
                if (stm != "GCM" && run)
                {
                    string exe = slnRow["EXE"].AsString();
                    if (exe.IsNotNull())
                    {
                       
                        //pBuild.Execute("Start \"" + stm + "\" " + exe.AddDoubleQuotes());
                        pBuild.Echo(INFO_URUCHOM + exe.AddDoubleQuotes() + " " + sln.AddDoubleQuotes() + " " + env.AddDoubleQuotes() + " " + server.AsString().AddDoubleQuotes());
                    }
                }
            }
            return i;
        }

        public static void ReplaceUrl(string exe, string sln, string env, int? server)
        {
            string config = exe + ".config";
            string configText = config.ReadFile();
            string mask = "((<setting name=.?WebServiceUrl.*?<value>)(.*?)(</value>\\s*</setting>))";

            if (configText.IsNotNull())
            {
                string dir = Path.GetDirectoryName(sln);
                string[] configs = Directory.GetFiles(dir, "app.config");
                if (configs.Length == 1)
                {
                    string orgConfig = configs[0].ReadFile();
                    if (orgConfig.IsNotNull())
                    {
                        string orgUrl = orgConfig.GetFirstMatch(mask, 3, System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Singleline);
                        string url = "";
                        if (env.IsNotNull())
                        {
                            string app = orgUrl.GetFirstMatch("/(Soft.*)");
                            DataRow sr = BrowserCache.GetRowForValue(Init.InitFormBrowserNames.Setup.Srodowiska, env);
                            if (sr != null)
                            {
                                url = sr["STP_SR_URL"].AsString();
                                url = url.XReplace("/GcmWebServices", "/" + app);
                            }
                        }
                        else
                        {
                            url = orgUrl;
                            if (server.HasValue)
                            {
                                DataRow row = BrowserCache.GetRowForValue(Init.InitFormBrowserNames.Setup.Serwery, server.Value);
                                if (row != null)
                                {
                                    string port = row["STP_SRW_PORT"].AsString();
                                    string host = row["STP_SRW_HOST"].AsString();
                                    url = url.XReplace("(localhost:\\d*)", host + ":" + port);
                                }
                            }
                        }
                        if (url.IsNotNull())
                        {
                            orgConfig = orgConfig.XReplace(mask, "$2" + url + "$4", System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Singleline);
                            orgConfig.WriteToFile(config, writeLine: false);
                        }
                    }
                }
            }
        }

        public static void TryCleanTmpBhFiles(string brancz)
        {
            Task.Factory.StartNew(CleanTmpBHFiles, brancz);
        }
        private static void CleanTmpBHFiles(object br)
        {
            string brancz = br as string;
            if (brancz.IsNull())
                return;

            GuiDataSet ds = new GuiDataSet();
            string vs = "";
            string cfg = "";
            ReadBranch(brancz, ds, out vs, out cfg);
            var devs = GlobalTools.FilesTools.GetDevEnvs();
            foreach (DataRow r in ds.APPS.Select())
            {
                try
                {
                    string slnFile = r["SLN"].AsString();
                    string[] files = Directory.GetFiles(Path.GetDirectoryName(slnFile), "*_BH_TMP*", SearchOption.TopDirectoryOnly);
                    if (files != null)
                    {
                        foreach (string f in files)
                        {
                            try
                            {
                                if (GlobalTools.FilesTools.GetDevEnv(f, devs) == null)
                                {
                                    File.Delete(f);
                                }
                            }
                            catch { }
                        }
                    }
                }
                catch { }
            }
        }

        private static string MakeValidFileName(string name)
        {
            var builder = new StringBuilder();
            var invalid = System.IO.Path.GetInvalidFileNameChars();
            foreach (var cur in name)
            {
                if (!invalid.Contains(cur))
                {
                    builder.Append(cur);
                }
                else
                {
                    builder.Append("_");
                }
            }
            return builder.ToString();
        }

        public static string GetFilteredSlnFileName(string stm, GuiDataSet ds, string templateName, bool includeGcm = false)
        {
            string newFile = string.Empty;
            DataRow slnRow = ds.APPS.SelectFirstRow("STM = " + stm.EscapeSql());
            if (slnRow != null)
            {
                string slnFile = slnRow["SLN"].AsString();
                string randomFile = string.Empty;
                if (templateName.IsNotNull() && OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Work_Group.Gui.NazwaProjektuZSzablonu))
                {
                    randomFile = MakeValidFileName(templateName);
                }
                else
                {
                    DataRow[] projects = ds.PROJEKTY.Select("STM = " + stm.EscapeSql());

                    foreach (DataRow row in projects)
                    {
                        if (row["BUDUJ"].AsBool())
                            randomFile = randomFile.AppendString("_") + row["NAZWA"].ToString().XReplace("^" + stm.XEscape(), "", RegexOptions.IgnoreCase);
                    }
                }
                if (includeGcm && stm != "GCM")
                {
                    randomFile = randomFile.AppendString("_GCM");
                    if ( templateName.IsNullOrEmpty() || !OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Work_Group.Gui.NazwaProjektuZSzablonu))
                    {
                        DataRow[] projects = ds.PROJEKTY.Select("STM = 'GCM'");
                        foreach (DataRow row in projects)
                        {
                            if (row["BUDUJ"].AsBool())
                                randomFile = randomFile.AppendString("_") + row["NAZWA"].ToString().XReplace("^" + stm.XEscape(), "", RegexOptions.IgnoreCase);
                        }
                    }
                }
                if (randomFile.Length > 64)
                    randomFile = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());

                newFile = slnFile.XReplace("\\.sln", "_BH_TMP_" + randomFile + ".sln");
            }
            return newFile;
        }

        public static string CreateFilteredSln(string stm, GuiDataSet ds, string templateName, bool includeGcm = false)
        {
            string newFile = GetFilteredSlnFileName(stm, ds, templateName, includeGcm);
            DataRow slnRow = ds.APPS.SelectFirstRow("STM = " + stm.EscapeSql());
            if (slnRow != null && newFile.IsNotNull())
            {
                DataRow[] projects = ds.PROJEKTY.Select("STM = " + stm.EscapeSql());

                if (slnRow != null)
                {
                    string slnFile = slnRow["SLN"].AsString();
                    string str = slnFile.ReadFile();
                    string code="";
                    string projectSearchstr = "Project\\(\"[^\"]*\"\\) = \"\\w*\", \"[^\"]*\", \"[CODE]\".*?EndProject\\s+";
                    string BuildSearchStr = "^.*?[CODE].*?$\\s*^";
                    string BuildSearchStr2 = "^\\s*[CODE].*?$\\s*^";
                    foreach (DataRow row in projects)
                    {
                        code = row["KOD"].AsString();

                        if (!row["BUDUJ"].AsBool())
                        {
                            string searchstr = projectSearchstr.Replace("[CODE]", code.XEscape());

                            str = str.XReplace(searchstr, "", System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                            searchstr = BuildSearchStr.Replace("[CODE]", code.XEscape());
                            str = str.XReplace(searchstr, "", System.Text.RegularExpressions.RegexOptions.Multiline | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                        }
                    }
                    str = str.XReplace("EndProject(\\s+EndProject)+", "EndProject");
                    if (includeGcm && stm != "GCM")
                    {
                        DataRow slnRowGcm = ds.APPS.SelectFirstRow("STM = 'GCM'");
                        if (slnRowGcm != null)
                        {
                            string slnFileGcm = slnRowGcm["SLN"].AsString();
                            string strGcm = slnFileGcm.ReadFile();

                            projects = ds.PROJEKTY.Select("STM = 'GCM'");
                            string ProjectSection = "";
                            string BuildSection = "";
                            foreach (DataRow row in projects)
                            {
                                code = row["KOD"].AsString();

                                if (!row["BUDUJ"].AsBool() && row["NAZWA"].ToString() != "SoftGcm")
                                {
                                    string searchstr = projectSearchstr.Replace("[CODE]", code.XEscape());

                                    strGcm = strGcm.XReplace(searchstr, "", System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                                    searchstr = BuildSearchStr.Replace("[CODE]", code.XEscape());
                                    strGcm = strGcm.XReplace(searchstr, "", System.Text.RegularExpressions.RegexOptions.Multiline | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                                }
                            }
                            strGcm = strGcm.XReplace("EndProject(\\s+EndProject)+", "EndProject");
                            var list = strGcm.GetMatches(projectSearchstr.Replace("[CODE]",".*?"), 0, System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                            foreach (var l in list)
                            {
                                ProjectSection = ProjectSection.AppendLine(l.TrimEnd());
                            }

                            list = strGcm.GetMatches(BuildSearchStr2.Replace("[CODE]", "\\{[^}]*\\}\\."), 0, System.Text.RegularExpressions.RegexOptions.Multiline | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                            if (list != null)
                            {
                                foreach (var l in list)
                                    BuildSection = BuildSection.AppendLine(l.TrimEnd());
                            }
                            DataRow softGcmRow = ds.PROJEKTY.SelectFirstRow("STM = 'GCM' AND NAZWA = 'SoftGcm'");
                            if (softGcmRow != null)
                            {
                                code = softGcmRow["KOD"].AsString();
                                string gcmSect = "\tProjectSection(ProjectDependencies) = postProject" + Constants.NewLineLinux +
                                                 "\t\t" + code + " = " + code + Constants.NewLineLinux +
                                                 "\tEndProjectSection" + Constants.NewLineLinux;

                                str = str.XReplace("(EndProject\\s+)", gcmSect + "$1");
                            }

                            if (ProjectSection.IsNotNull() && BuildSection.IsNotNull())
                            {
                                int idx = str.LastIndexOf("EndProject");
                                if (idx > -1)
                                {
                                    ProjectSection = ProjectSection.XReplace("..\\\\(\\w*)", @"..\..\..\..\gcm\src\gui\" + "$1");
                                    ProjectSection = ProjectSection.XReplace("SoftGcm\\.csproj", @"..\..\..\..\gcm\src\gui\SoftGcm\SoftGcm.csproj");
                                    str = str.Insert(idx + 10, Constants.NewLineLinux + ProjectSection);
                                    idx = str.IndexOf("GlobalSection(ProjectConfigurationPlatforms) = postSolution");
                                    if (idx > -1)
                                    {
                                        idx = str.IndexOf("\tEndGlobalSection", idx);
                                        if (idx > -1)
                                        {
                                            str = str.Insert(idx, BuildSection + Constants.NewLineLinux);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    //remove empty folder projects
                    str = str.XReplace("Project\\(\"\\{2150E333-8FDC-42A3-9474-1A3956D46DE8\\}\"\\) = \"\\w*\", \"\\w*\", \"\\{[A-Z0-9\\-]*\\}\"\\s*EndProject\\s*", "");
                    str = Constants.NewLineLinux + str.TrimStartEnd();
                    str.WriteToFile(newFile, writeLine: false);
                }
            }
            return newFile;
        }
        private static int SetSln(string stm, GuiDataSet ds)
        {
            DataRow slnRow = ds.APPS.SelectFirstRow("STM = " + stm.EscapeSql());
            List<string> buildProj = new List<string>();

            if (slnRow != null)
            {
                string slnFile = slnRow["SLN"].AsString();
                string tmpSlnFile = slnFile.XReplace("\\.sln", "_BH_TMP.sln");

                string str = slnFile.ReadFile();
                DataRow[] projects = ds.PROJEKTY.Select("STM = " + stm.EscapeSql());
                foreach (DataRow row in projects)
                {
                    string code = row["KOD"].AsString();

                    if (!row["BUDUJ"].AsBool())
                    {
                        string searchstr = code.XEscape() + "\\.(.*)\\.Build\\.0 = (.*)";
                        searchstr = "^\\s*" + searchstr + "\\s*$\\s*^";
                        str = str.XReplace(searchstr, "", System.Text.RegularExpressions.RegexOptions.Multiline | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                    }
                }
                str.TrimStartEnd().WriteToFile(tmpSlnFile, writeLine: false);
                List<string> l = str.GetMatches("\\{(.*?)\\}\\.(Release.*?.Build\\.0)", 1, System.Text.RegularExpressions.RegexOptions.Multiline | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                foreach (string s in l)
                    if (!buildProj.Contains(s))
                        buildProj.Add(s);
            }
            return buildProj.Count;
        }
        
        public static bool FindError(string str)
        {
            string[] errors = OptionCache.GetOptionStringValue(Init.InitFormOptionNames.Work_Group.Gui.OznaczenieBledow).XSplit("\n");
            foreach (string s in errors)
            {
                if (s.IsNotNullOrWhiteSpace() && str.XMatch(s.Trim('\r')))
                {
                    return true;
                }
            }
            return false;
        }
        public static bool ShouldAddLog(string str)
        {
            if (FindError(str))
                return true;
            string[] opt = OptionCache.GetOptionStringValue(Init.InitFormOptionNames.Work_Group.Gui.Wyswietlanie).XSplit("\n");
            foreach (string s in opt)
            {
                if (s.IsNotNullOrWhiteSpace() && str.XMatch(s.Trim('\r')))
                {
                    return true;
                }
            }
            return false;
        }
        
        private class BudujProcInfo
        {

            public BudujProcInfo()
            {
            }
           
            #region properties
            public string AlertId
            {
                get;
                set;
            }
            public bool StopOnError
            {
                get;
                set;
            }
            public string Brancz { get; set; }
            public string LogFile { get; set; }
            public bool ShowInfo { get; set; }
            public DataRow Row
            {
                get;
                set;
            }
            
            #endregion

            public bool Error
            {
                get;
                set;
            }

            List<BuildStm> systemy = new List<BuildStm>();
            BuildStm curStm = null;
            string projekt = "";
            int buildProj = 0;
            int buildProjAll = 0;
            int allProjs = 0;
            
            private void SetProgressTest()
            {
                if (systemy != null && curStm != null)
                {
                    int cSys = systemy.IndexOf(curStm) + 1;
                    int cProj = Math.Max(1, buildProj);
                    string p = "";
                    if (buildProj > 0)
                        p = projekt;
                    string text = "System: " + cSys + "/" + systemy.Count + " (" + curStm.System + ")";

                    if (systemy.Count > 1)
                    {
                        int ba = Math.Max(buildProjAll, 1);
                        text += ";  Projekty: " + ba + "/" + allProjs;
                    }
                    text += ";  Obecny Projekt: " + cProj + "/" + curStm.Projects + ";  " + p;

                    text = "Budowanie GUI [" + Brancz + "]" + Constants.NewLineLinux + text;
                    FormMain.UpdateAlertText(AlertId, text.Replace(";  ", Constants.NewLineLinux));
                }
            }
            private void SetCurStm(BuildStm s)
            {
                if (curStm != s)
                {
                    curStm = s;
                    buildProj = 0;
                    projekt = "";
                    SetProgressTest();
                }
            }

            public void SetData(string str)
            {
                if (str.XMatch("^" + BudowanieGuiTools.INFO_POCZATEK_BUDOWANIA))
                {
                    if (systemy != null)
                    {
                        string stm = str.GetFirstMatch("^" + BudowanieGuiTools.INFO_POCZATEK_BUDOWANIA + " (\\w*)");
                        if (stm != null)
                        {
                            foreach (BuildStm s in systemy)
                            {
                                if (s.System.ToLower() == stm.ToLower())
                                {
                                    SetCurStm(s);
                                    break;
                                }
                            }
                        }
                    }
                }
                if (str.XMatch("Build started"))
                {
                    buildProjAll++;
                    buildProj++;
                    projekt = str.GetFirstMatch("Build started:\\sProject:\\s(\\w*)");
                    SetProgressTest();
                }
            }
            
            public void SetSystems(BuildStm[] stms)
            {
                systemy.AddRange(stms);
                foreach (BuildStm s in stms)
                    allProjs += s.Projects;
                if (stms.Length > 0)
                    SetCurStm(stms[0]);
            }
        }

        private static Dictionary<Process, BudujProcInfo> budowanieProcess = new Dictionary<Process, BudujProcInfo>();

        private static int BudujId;

        public static void Buduj(string brancz, string template, bool clean, string cfg, string vs, bool showInfo, bool stopOnError, DataRow row)
        {
            if (brancz.IsNull())
                brancz = Setup.Brancze.BranczeTools.ActiveBranch;
            if (brancz.IsNull())
            {
                FormMain.ShowErrorAlert("Przerwanie zadania Budowanie Gui z powodu braku brancza.");
                return;
            }

            GuiDataSet ds = new GuiDataSet();
            string sVs = "";
            string sKonfig = "";
            ReadBranch(brancz, ds, out sVs, out sKonfig);
            if (template.IsNotNull())
            {
                GuiDataSet templateDs = new GuiDataSet();
                ReadTemplate(templateDs, template);
                ApplyTemplate(ds, templateDs);
            }
            if (vs.IsNotNull())
                sVs = vs;
            if (cfg.IsNotNull())
                sKonfig = cfg;

            Process p = GlobalTools.CreateCMDProcess(Buduj_Data);
            GlobalTools.ProcessTools.SetEnvVariable(p, brancz);
            BudujProcInfo i = new BudujProcInfo();
            i.Row = row;
            i.AlertId = "GUI_BUILD_"+BudujId;
            i.StopOnError = stopOnError;
            i.Brancz = brancz;
            i.LogFile = GlobalTools.FilesTools.GetTemplLogFile("Budowanie_GUI_" + brancz);
            i.ShowInfo = showInfo;
            ("Zadanie budowania brancza " + brancz + ", Schemat: " +
                template + ", VS:" + sVs + ", Konfig:" + sKonfig + Constants.NewLineLinux + Constants.NewLineLinux).WriteToFile(i.LogFile);
            BudujId++;
            if (showInfo)
            {
                FormMain.ShowAlert("Budowanie Gui\n" + brancz, Properties.Resources.burn_gui24, new FormMain.AlertInfo(true, i.AlertId));
            }
            budowanieProcess.Add(p, i);
            p.EchoOff();
            BuildStm[] b =Buduj(ds, sVs, p, false, clean, sKonfig, "", null);
            i.SetSystems(b);
        }

        private static void Buduj_Data(object sender, DataReceivedEventArgs e)
        {
            string str = "";
             str = e.Data.AsString();
             BudujProcInfo info=null;
             if (budowanieProcess.ContainsKey((Process)sender))
                 info = budowanieProcess[(Process)sender];
             if (info != null)
             {
                 str.AppendToFile(info.LogFile);
                 info.SetData(str);
             }
             if (FindError(str))
             {
                 if (info != null && info.StopOnError)
                 {
                     FormMain.ShowAlert("Zadania Budowanie Gui [" + info.Brancz + "] przerwane z powodu błędu.", FormMain.ErrorImg, new FormMain.AlertInfo(true));
                     Process.Start(info.LogFile);
                     budowanieProcess.Remove((Process)sender);
                     if (info.Row != null && info.Row["STATUS"].AsString() == Zadanie.Statusy.W_Trakcie)
                     {
                         try
                         {
                             if (FormMain.Instance.InvokeRequired)
                             {
                                 FormMain.Instance.Invoke(new Action(() =>
                                 {
                                     info.Row["STATUS"] = BuildHelper.Scheduler.Zadanie.Statusy.Blad;
                                 }));
                             }
                             else
                             {
                                 info.Row["STATUS"] = BuildHelper.Scheduler.Zadanie.Statusy.Blad;
                             }
                         }
                         catch (Exception ex) { ex.Log(); }
                     }
                     try
                     {
                         ((Process)sender).KillProcessTree();
                         ((Process)sender).Dispose();
                     }
                     catch { }
                 }
                 else
                 {
                     if (info != null)
                         info.Error = true;
                 }
             }
             if (str.XMatch("^" + INFO_KONIEC_BUDOWANIA))
             {
                 if (info != null)
                 {
                     if (info.Row != null && info.Row["STATUS"].AsString() == Zadanie.Statusy.W_Trakcie)
                     {
                         string status;
                         if (info.Error)
                             status = Zadanie.Statusy.ZakonczoneZBledem;
                         else
                             status = Zadanie.Statusy.Zakonczone;
                         try
                         {
                             if (FormMain.Instance.InvokeRequired)
                             {
                                 FormMain.Instance.Invoke(new Action(() =>
                                 {
                                     info.Row["STATUS"] = status;
                                 }));
                             }
                             else
                             {
                                 info.Row["STATUS"] = status;
                             }
                         }
                         catch (Exception ex) { ex.Log(); }
                     }
                     FormMain.CloseAlertById(info.AlertId);
                     Process.Start(info.LogFile);
                     budowanieProcess.Remove((Process)sender);
                     if (info.ShowInfo)
                     {
                         FormMain.ShowInfoAlert("Koniec zadania budowania " + info.Brancz);
                     }
                     try
                     {
                         ((Process)sender).KillProcessTree();
                         ((Process)sender).Dispose();
                     }
                     catch { }
                 }
             }
        }
    }

    public class BuildStm
    {
        public BuildStm(string system, int projects)
        {
            System = system;
            Projects = projects;
        }
        public string System
        {
            get;
            set;
        }
        public int Projects
        {
            get;
            set;
        }
    }
}
